﻿//-----------------------------------------------------------------------
// <copyright file="AuthorizationServiceBase.Roles.cs" company="Alan Rodrigues">
//     Copyright (c) Alan Rodrigues. All rights reserved.
// </copyright>
// <developed>Alan Rodrigues (operninha@gmail.com)</developed>
//-----------------------------------------------------------------------

using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Authorization
{
    using System;
    using Properties;

    public partial class AuthorizationServiceBase
    {
        #region ApplicationGroups
        public ApplicationGroupCollection GetAllApplicationGroups(string applicationName, string scopeName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);
            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.GetAllApplicationGroups", Resources.invalid_application);
            }
    
            return application.GetApplicationGroups(scopeName);
        }

        /// <summary>
        /// Retorna o nome dos papeis do sistema
        /// </summary>
        /// <param name="applicationName">nome da Application</param>
        /// <param name="scopeName">Name do <seealso cref="Scope"/> onde será feita a busca dos papeis</param>
        /// <returns>Name dos papeis do Sistema</returns>
        public string[] GetAllApplicationGroupNames(string applicationName, string scopeName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");

            var app = AuthorizationStoreManager.GetApplication(applicationName);

            if (app == null)
            {
                throw new AuthorizationException("AuthorizationService.GetAllApplicationGroupNames", Resources.invalid_application);
            }

            return app.GetApplicationGroupNames(scopeName);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="scopeName"></param>
        /// <param name="roleName"></param>
        /// <returns></returns>
        public bool ApplicationGroupExists(string applicationName, string scopeName, string applicationGroupName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");
            var app = AuthorizationStoreManager.GetApplication(applicationName);

            if (app == null)
            {
                throw new AuthorizationException("AuthorizationService.RoleAssignmentExists", Resources.invalid_application);
            }

            return app.ApplicationGroupExists(applicationGroupName, scopeName);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="applicationName"></param>
        /// <param name="scopeName"></param>
        /// <param name="roleAssignmentName"></param>
        /// <returns></returns>
        public ApplicationGroup GetApplicationGroup(string applicationName, string scopeName, string applicationGroupName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");

            var app = AuthorizationStoreManager.GetApplication(applicationName);

            if (app == null)
            {
                throw new AuthorizationException("AuthorizationService.GetApplicationGroup", Resources.invalid_application);
            }

            return app.GetApplicationGroup(applicationGroupName, scopeName);
        }

        public ApplicationGroup CreateApplicationGroup(string applicationName, string scopeName, string applicationGroupName, string description)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");

            Application application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.CreateApplicationGroup", Resources.invalid_application);
            }

            var role = application.CreateApplicationGroup(applicationGroupName, description, scopeName);
            role.Save();
            return role;
        }

        public void DeleteApplicationGroup(string applicationName, string scopeName, string applicationGroupName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.DeleteApplicationGroup", Resources.invalid_application);
            }

            application.DeleteApplicationGroup(applicationGroupName, scopeName);
            application.Save();
        }

        public void UpdateApplicationGroup(string applicationName, string scopeName, string applicationGroupName, string newApplicationGroupName, string newDescription)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");
            SecUtility.CheckParameter(ref newApplicationGroupName, true, true, false, 64, "newApplicationGroupName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.UpdateApplicationGroup", Resources.invalid_application);
            }

            var role = application.UpdateApplicationGroup(applicationGroupName, scopeName, newApplicationGroupName, newDescription);
            role.Save();
        }


        public void AddUsersToApplicationGroup(string applicationName, string scopeName, string[] Sids, string[] applicationGroupNames)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckArrayParameter(ref applicationGroupNames, true, true, false, 64, "applicationGroupNames");
            SecUtility.CheckArrayParameter(ref Sids, true, true, false, 64, "Sids");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.AddUsersToApplicationGroup", Resources.invalid_application);
            }

            foreach (var appGroupName in applicationGroupNames)
            {
                var appGroup = application.GetApplicationGroup(appGroupName, scopeName);
                appGroup.AddMembers(Sids);
                appGroup.Save();
            }
        }

        public void AddUserNamesToApplicationGroups(string applicationName, string scopeName, string[] usernames, string[] applicationGroupNames)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckArrayParameter(ref applicationGroupNames, true, true, false, 64, "applicationGroupNames");
            SecUtility.CheckArrayParameter(ref usernames, true, true, false, 64, "usernames");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.AddUserNamesToApplicationGroups", Resources.invalid_application);
            }

            foreach (var appGroupName in applicationGroupNames)
            {
                var appGroup = application.GetApplicationGroup(appGroupName, scopeName);
                appGroup.AddMemberNames(usernames);
                appGroup.Save();
            }
        }

        public string[] FindUsersInApplicationGroup(string usernameToMatch, string applicationName, string scopeName, string applicationGroupName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref usernameToMatch, true, true, false, 64, "usernameToMatch");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");
            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.FindUsersInApplicationGroup", Resources.invalid_application);
            }

            var appGroup = application.GetApplicationGroup(applicationGroupName, scopeName);
            var users = appGroup != null ? appGroup.GetMembers() : null;

            if (users == null)
                return null;

            var usersResult = new List<string>();

            var reg = new Regex(usernameToMatch);
            foreach (var user in users)
            {
                if (reg.IsMatch(user))
                    usersResult.Add(user);
                else if (IsUserInApplicationGroup(user, applicationName, scopeName, applicationGroupName))
                    usersResult.Add(user);
            }

            return usersResult.ToArray();
        }

        public string[] GetUsersInApplicationGroup(string applicationName, string scopeName, string applicationGroupName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckParameter(ref applicationGroupName, true, true, false, 64, "applicationGroupName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.GetUsersInApplicationGroup", Resources.invalid_application);
            }

            var appGroup = application.GetApplicationGroup(applicationGroupName, scopeName);
            return appGroup != null ? appGroup.GetMemberNames() : null;
        }


        public void RemoveUsersFromApplicationGroups(string applicationName, string scopeName, string[] usernames, string[] applicationGroupsName)
        {
            SecUtility.CheckParameter(ref applicationName, true, true, false, 64, "applicationName");
            SecUtility.CheckArrayParameter(ref usernames, true, true, false, 64, "usernames");
            SecUtility.CheckArrayParameter(ref applicationGroupsName, true, true, false, 64, "applicationGroupsName");

            var application = AuthorizationStoreManager.GetApplication(applicationName);

            if (application == null)
            {
                throw new AuthorizationException("AuthorizationService.RemoveUsersFromApplicationGroups", Resources.invalid_application);
            }
            foreach (var roleAssignmentName in applicationGroupsName)
            {
                var appGroup = application.GetApplicationGroup(roleAssignmentName, scopeName);
                if (appGroup != null)
                {
                    appGroup.DeleteMemberNames(usernames);
                    appGroup.Save();
                }
            }
        }

        #endregion
    }
}
